package cn._2dland.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

public class Base64 {
	private static final String BASE64_CHAR = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

	/**
	 * Base64编码
	 * 
	 * @param b
	 * @return
	 */
	public static String encode(byte[] b) {
		if(b == null)
			return null;

		StringBuffer buf = new StringBuffer();
		int len = b.length;
		for(int i = 0; i < len; ) {
			// 读取第一个字节
			int b1 = b[i++];

			// 编码后的四个字符索引
			int e1 = (b1 & 0xfc) >> 2;
 			int e2 = (b1 & 0x03) << 4;
			int e3 = 64;
			int e4 = 64;

			// 尝试读取第二个字节
			if(i < len) {
				int b2 = b[i++];
				e2 |= (b2 & 0xf0) >> 4;
				e3 = (b2 & 0x0f) << 2;
			}

			// 尝试读取第三个字节
			if(i < len) {
				int b3 = b[i++];
				e3 |= (b3 & 0xc0) >> 6;
				e4 = b3 & 0x3f;
			}

			buf.append(BASE64_CHAR.charAt(e1))
				.append(BASE64_CHAR.charAt(e2))
				.append(BASE64_CHAR.charAt(e3))
				.append(BASE64_CHAR.charAt(e4));
		}

		return buf.toString();
	}

	/**
	 * Base64解码
	 * 
	 * @param str
	 * @return
	 */
	public static byte[] decode(String str) {
		byte[] buf = null;

		if(str == null)
			return null;

		// 获取字符串长度
		int len = str.length();
		if(len % 4 != 0)
			return null;

		// 开始解码
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		for(int i=0; i < len; i+=4) {
			int e1 = BASE64_CHAR.indexOf( str.charAt(i) );
			int e2 = BASE64_CHAR.indexOf( str.charAt(i + 1) );
			int e3 = BASE64_CHAR.indexOf( str.charAt(i + 2) );
			int e4 = BASE64_CHAR.indexOf( str.charAt(i + 3) );

			int d1 = ((e1 & 0x3f) << 2) | ((e2 & 0x30) >> 4);
			int d2 = ((e2 & 0x0f) << 4) | ((e3 & 0x3c) >> 2);
			int d3 = ((e3 & 0x03) << 6) | (e4 & 0x3f);

			baos.write(d1);
			if(d2 != 0) baos.write(d2);
			if(d3 != 0) baos.write(d3);
		}
		try {
			baos.flush();
			buf = baos.toByteArray();
			baos.close();
		} catch (IOException e) {
			buf = null;
		}

		return buf;
	}
}
